# protoc -I=$SRC_DIR --grpc_out=$DST_DIR --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` $SRC_DIR/xxx.proto 生成服务端代码
# protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto
message(STATUS "using protoc: ${PROTOBUF_PROTOC_EXECUTABLE}")

# 示例：kylin_ai_generate_grpc_proto_source(RETURNED_GRPC_SOURCE_FILES vector-db common feder msg rg schema milvus)
function(kylin_ai_generate_grpc_proto_source RETURNED_GRPC_SOURCE_FILES PATH)
    set(PROTO_FILE_NAMES)
    set(PROTO_FILES)
    set(GENERATE_PROTO_FILES)
    set(SRC_DIR /usr/share/kylin-ai/protocols/grpc/${PATH})

    # ARGN 是函数传入以外的参数
    foreach(ARG ${ARGN})
        list(APPEND PROTO_FILE_NAMES ${ARG})
    endforeach()

    foreach(PROTO_FILE_NAME ${PROTO_FILE_NAMES})
        set(PROTO_FILE ${SRC_DIR}/${PROTO_FILE_NAME}.proto)
        if(NOT EXISTS ${PROTO_FILE})
            message(FATAL_ERROR "grpc-proto-gen: Unable to find proto file: ${PROTO_FILE}")
        else()
            list(APPEND PROTO_FILES ${PROTO_FILE})
        endif()
    endforeach()

    foreach(PROTO_FILE ${PROTO_FILES})
        get_filename_component(PROTO_FILE_NAME ${PROTO_FILE} NAME)
        string(REPLACE ".proto" "" PROTO_FILE_NAME ${PROTO_FILE_NAME})

        add_custom_command(
                OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.pb.cc
                       ${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.pb.h
                DEPENDS ${PROTO_FILE}
                        ${PROTOBUF_PROTOC_EXECUTABLE}
                COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
                ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR}
                     -I ${SRC_DIR}
                     ${PROTO_FILE}
        )

        list(APPEND GENERATE_PROTO_FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.pb.cc")
        list(APPEND GENERATE_PROTO_FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.pb.h")
    endforeach()

    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    set(${RETURNED_GRPC_SOURCE_FILES} ${GENERATE_PROTO_FILES} PARENT_SCOPE)
endfunction(kylin_ai_generate_grpc_proto_source RETURNED_GRPC_SOURCE_FILES)

function(kylin_ai_generate_grpc_proto_service RETURNED_GRPC_SERVICE_FILES PATH)
    find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)
    message(STATUS "using protoc: ${GRPC_CPP_PLUGIN}")

    set(PROTO_FILE_NAMES)
    set(PROTO_FILES)
    set(GENERATE_PROTO_FILES)
    set(SRC_DIR /usr/share/kylin-ai/protocols/grpc/${PATH})

    # ARGN 是函数传入以外的参数
    foreach(ARG ${ARGN})
        list(APPEND PROTO_FILE_NAMES ${ARG})
    endforeach()

    foreach(PROTO_FILE_NAME ${PROTO_FILE_NAMES})
        set(PROTO_FILE ${SRC_DIR}/${PROTO_FILE_NAME}.proto)
        if(NOT EXISTS ${PROTO_FILE})
            message(FATAL_ERROR "grpc-proto-gen: Unable to find proto file: ${PROTO_FILE}")
        else()
            list(APPEND PROTO_FILES ${PROTO_FILE})
        endif()
    endforeach()

    foreach(PROTO_FILE ${PROTO_FILES})
        get_filename_component(PROTO_FILE_NAME ${PROTO_FILE} NAME)
        string(REPLACE ".proto" "" PROTO_FILE_NAME ${PROTO_FILE_NAME})

        add_custom_command(
                OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.grpc.pb.cc
                       ${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.grpc.pb.h
                DEPENDS ${PROTO_FILE}
                        ${PROTOBUF_PROTOC_EXECUTABLE}
                        ${GRPC_CPP_PLUGIN}
                COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
                ARGS --grpc_out ${CMAKE_CURRENT_BINARY_DIR}
                     -I ${SRC_DIR}
                     --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN}
                     ${PROTO_FILE}
        )

        list(APPEND GENERATE_PROTO_FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.grpc.pb.cc")
        list(APPEND GENERATE_PROTO_FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROTO_FILE_NAME}.grpc.pb.h")
    endforeach()

    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    set(${RETURNED_GRPC_SERVICE_FILES} ${GENERATE_PROTO_FILES} PARENT_SCOPE)
endfunction(kylin_ai_generate_grpc_proto_service RETURNED_GRPC_SERVICE_FILES)
